package com.woniu.crowd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.crowd.common.CrowdException;
import com.woniu.crowd.infra.config.AlipayConfig;
import com.woniu.crowd.infra.model.CrowdLog;
import com.woniu.crowd.infra.model.CrowdOrder;
import com.woniu.crowd.infra.model.CrowdUserRele;
import com.woniu.crowd.infra.model.CrowdfundingProducts;
import com.woniu.crowd.infra.mapper.CrowdfundingProductsMapper;
import com.woniu.crowd.infra.model.es.CrowdEsModel;
import com.woniu.crowd.service.CrowdLogService;
import com.woniu.crowd.service.CrowdOrderService;
import com.woniu.crowd.service.CrowdUserReleService;
import com.woniu.crowd.service.CrowdfundingProductsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.crowd.service.dto.CrowdEsModelDto;
import com.woniu.crowd.service.dto.CrowdProductDto;
import com.woniu.crowd.service.dto.PageCrowdEsDto;
import com.woniu.crowd.service.form.SearchCrowdForm;
import com.woniu.crowd.service.form.UPdateCrowdForm;
import com.woniu.crowd.service.form.upCrowdForm;
import com.woniu.exception.LXLGException;
import com.woniu.product.client.ProductQueryClient;
import com.woniu.product.client.result.SpuResultInfo;
import com.woniu.result.Result;
import com.woniu.util.DateUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 众筹表 服务实现类
 * </p>
 *
 * @author Lucas
 * @since 2022-11-26
 */
@Service
public class CrowdfundingProductsServiceImpl extends ServiceImpl<CrowdfundingProductsMapper, CrowdfundingProducts> implements CrowdfundingProductsService {
    @Resource
    private ProductQueryClient productQueryClient;
    @Resource
    private ElasticsearchOperations eo;

    @Resource
    private CrowdLogService crowdLogService;

    @Resource
    private CrowdUserReleService crowdUserReleService;

    @Resource
    private CrowdOrderService crowdOrderService;

    @Override
    public Result upCrowd(upCrowdForm upCrowdForm) {
        SpuResultInfo spu = productQueryClient.getSpuInfoBySpuId(upCrowdForm.getProductId(), -1).getData();
        if (spu == null) throw new LXLGException(CrowdException.CROWD_PRODUCT_NON_EXISTENT);
        if (spu.getSpuStatus().equals("ON_SALE")) throw new LXLGException(CrowdException.CROWD_ON_THE_SHELF);
        CrowdfundingProducts crowd = BeanUtil.copyProperties(upCrowdForm, CrowdfundingProducts.class);
        crowd.setCroedState("CREATED");
        crowd.setTotalAmount(new BigDecimal(0));
        crowd.setUserCount(0);
        save(crowd);
        CrowdEsModel crowdEsModel = BeanUtil.copyProperties(spu, CrowdEsModel.class);
        crowdEsModel.setId(crowd.getId());
        crowdEsModel.setSpuId(crowd.getProductId());
        crowdEsModel.setTargetAmount(crowd.getTargetAmount());
        crowdEsModel.setTotalAmount(crowd.getTotalAmount());
        crowdEsModel.setUserCount(crowd.getUserCount());
        crowdEsModel.setStartDate(crowd.getStartDate());
        crowdEsModel.setEndDate(crowd.getEndDate());
        eo.save(crowdEsModel);

        CrowdLog crowdLog = new CrowdLog();
        crowdLog.setLogUser(upCrowdForm.getLogUser());
        crowdLog.setLogTime(DateUtil.parseDateLong());
        crowdLog.setLogContnet("上架众筹商品");
        crowdLog.setCrowdId(crowd.getId());

        crowdLogService.save(crowdLog);
        return Result.getInstance().setMsg("上成功").setCode(200);
    }

    @Override
    public Result searchCrowd(SearchCrowdForm searchCrowdForm) {
        NativeSearchQueryBuilder nsqb = new NativeSearchQueryBuilder();
        BoolQueryBuilder bqb1 = new BoolQueryBuilder();
        BoolQueryBuilder bqb2 = new BoolQueryBuilder();
        //关键字
        if (searchCrowdForm.getKeyword() != null && !"".equals(searchCrowdForm.getKeyword().trim()) && searchCrowdForm.getKeyword().length() > 0) {

            bqb2.should().add(new MatchQueryBuilder("spuName", searchCrowdForm.getKeyword()));
            bqb2.should().add(new MatchQueryBuilder("categoryName", searchCrowdForm.getKeyword()));
            bqb2.should().add(new MatchQueryBuilder("introduction", searchCrowdForm.getKeyword()));
            bqb1.must().add(bqb2);
        }
        //价格区间
        RangeQueryBuilder rqb = null;
        if (searchCrowdForm.getStartPrice() != null && searchCrowdForm.getEndPrice() != null) {

            rqb = new RangeQueryBuilder("minPrice");
            rqb.gte(searchCrowdForm.getStartPrice());
            rqb.lte(searchCrowdForm.getEndPrice());
            bqb1.must().add(rqb);
        }
        RangeQueryBuilder rqb1 = new RangeQueryBuilder("minPrice");
        if (searchCrowdForm.getStartPrice() != null) {
            rqb1.gte(searchCrowdForm.getStartPrice());
            bqb1.must().add(rqb1);
        }
        if (searchCrowdForm.getEndPrice() != null) {
            rqb1.lte(searchCrowdForm.getEndPrice());
            bqb1.must().add(rqb1);
        }

        nsqb.withQuery(bqb1);
        //分页
        nsqb.withPageable(PageRequest.of(searchCrowdForm.getIndexPage() - 1, searchCrowdForm.getPageSize()));
        NativeSearchQuery nsq = nsqb.build();
        SearchHits<CrowdEsModel> sh = eo.search(nsq, CrowdEsModel.class);
        List<CrowdEsModelDto> bds = sh.getSearchHits().stream().map(searchhit -> {
            CrowdEsModelDto spuEsModelDto = BeanUtil.copyProperties(searchhit.getContent(), CrowdEsModelDto.class);
            return spuEsModelDto;
        }).collect(Collectors.toList());
        PageCrowdEsDto esDto = new PageCrowdEsDto();
        esDto.setTotal(sh.getTotalHits());
        esDto.setSpuEsList(bds);
        return Result.getInstance(PageCrowdEsDto.class).setData(esDto).setCode(200).setMsg("搜索成功");
    }

    /**
     * 修改es中的数据
     */
    @Override
    public void updateByCrowdId(UPdateCrowdForm uPdateCrowdForm) {
        CrowdEsModel crowdEsModel = eo.get(uPdateCrowdForm.getId() + "", CrowdEsModel.class);
        crowdEsModel.setTotalAmount(uPdateCrowdForm.getTotalAmount());
        crowdEsModel.setUserCount(uPdateCrowdForm.getUserCount());
        eo.save(crowdEsModel);
    }

    @Override
    public List<CrowdProductDto> listCrowdByUserId(Integer userId) {
        List<CrowdUserRele> crowdUserReles = crowdUserReleService.list(new QueryWrapper<CrowdUserRele>().eq("user_id", userId));
        if (crowdUserReles.size() <= 0) throw new LXLGException(CrowdException.CROWD_HAS_NOT_YET);

        System.out.println(crowdUserReles);
        List<Integer> collect = crowdUserReles.stream().map(o -> o.getCrowd()).distinct().collect(Collectors.toList());

        List<CrowdProductDto> crowdProductDtos = new ArrayList<>();

        System.out.println(crowdProductDtos);
        List<CrowdOrder> crowdOrderList=new ArrayList<>();
        for (Integer crowdId : collect) {
            crowdOrderList = crowdOrderService.list(new QueryWrapper<CrowdOrder>().eq("crowd_id", crowdId).eq("crowd_order_state", "PAID"));
            System.out.println(crowdOrderList);

        }
        for (CrowdOrder crowdOrder : crowdOrderList) {
            CrowdfundingProducts byId = getById(crowdOrder.getCrowdId());
            CrowdProductDto crowdProductDto = BeanUtil.copyProperties(byId, CrowdProductDto.class);

            if (Objects.equals(byId.getId(), crowdProductDto.getId())) {
                SpuResultInfo spu = productQueryClient.getSpuInfoBySpuId(crowdProductDto.getProductId(), -1).getData();
                if (spu == null) throw new LXLGException(CrowdException.CROWD_PRODUCT_NON_EXISTENT);
                crowdProductDto.setProductName(spu.getSpuName());
            }
            crowdProductDtos.add(crowdProductDto);
        }
        return crowdProductDtos;
    }


}
